#ifndef _IRQ_H_
#define _IRQ_H_

/* exception vector */
#define EXCEPTION_VECTOR_BASE		0xD0037400
#define pExceptionRESET				(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x00)))
#define pExceptionUNDEF				(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x04)))
#define pExceptionSWI					(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x08)))
#define pExceptionPABORT				(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x0c)))
#define pExceptionDABORT				(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x10)))
#define pExceptionRESERVED			(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x14)))
#define pExceptionIRQ					(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x18)))
#define pExceptionFIQ					(*((volatile unsigned long*)(EXCEPTION_VECTOR_BASE + 0x1c)))


#define VIC0_BASE		(0xf2000000)
#define VIC1_BASE		(0xf2100000)
#define VIC2_BASE		(0xf2200000)
#define VIC3_BASE		(0xf2300000)

#define VIC0_IRQSTATUS	(*((volatile unsigned long *)(VIC0_BASE + 0x00)))
#define VIC1_IRQSTATUS	(*((volatile unsigned long *)(VIC1_BASE + 0x00)))
#define VIC2_IRQSTATUS	(*((volatile unsigned long *)(VIC2_BASE + 0x00)))
#define VIC3_IRQSTATUS	(*((volatile unsigned long *)(VIC3_BASE + 0x00)))

#define VIC0_FIQSTATUS	(*((volatile unsigned long *)(VIC0_BASE + 0x04)))
#define VIC1_FIQSTATUS	(*((volatile unsigned long *)(VIC1_BASE + 0x04)))
#define VIC2_FIQSTATUS	(*((volatile unsigned long *)(VIC2_BASE + 0x04)))
#define VIC3_FIQSTATUS	(*((volatile unsigned long *)(VIC3_BASE + 0x04)))

#define VIC0_RAWINTR		(*((volatile unsigned long *)(VIC0_BASE + 0x08)))
#define VIC1_RAWINTR		(*((volatile unsigned long *)(VIC1_BASE + 0x08)))
#define VIC2_RAWINTR		(*((volatile unsigned long *)(VIC2_BASE + 0x08)))
#define VIC3_RAWINTR		(*((volatile unsigned long *)(VIC3_BASE + 0x08)))

#define VIC0_INTSELECT	(*((volatile unsigned long *)(VIC0_BASE + 0x0c)))
#define VIC1_INTSELECT	(*((volatile unsigned long *)(VIC1_BASE + 0x0c)))
#define VIC2_INTSELECT	(*((volatile unsigned long *)(VIC2_BASE + 0x0c)))
#define VIC3_INTSELECT	(*((volatile unsigned long *)(VIC3_BASE + 0x0c)))

#define VIC0_INTENABLE	(*((volatile unsigned long *)(VIC0_BASE + 0x10)))
#define VIC1_INTENABLE	(*((volatile unsigned long *)(VIC1_BASE + 0x10)))
#define VIC2_INTENABLE	(*((volatile unsigned long *)(VIC2_BASE + 0x10)))
#define VIC3_INTENABLE	(*((volatile unsigned long *)(VIC3_BASE + 0x10)))

#define VIC0_INTENCLEAR	(*((volatile unsigned long *)(VIC0_BASE + 0x14)))
#define VIC1_INTENCLEAR	(*((volatile unsigned long *)(VIC1_BASE + 0x14)))
#define VIC2_INTENCLEAR	(*((volatile unsigned long *)(VIC2_BASE + 0x14)))
#define VIC3_INTENCLEAR	(*((volatile unsigned long *)(VIC3_BASE + 0x14)))

#define VIC0_SOFTINT		(*((volatile unsigned long *)(VIC0_BASE + 0x18)))
#define VIC1_SOFTINT		(*((volatile unsigned long *)(VIC1_BASE + 0x18)))
#define VIC2_SOFTINT		(*((volatile unsigned long *)(VIC2_BASE + 0x18)))
#define VIC3_SOFTINT		(*((volatile unsigned long *)(VIC3_BASE + 0x18)))

#define VIC0_SOFTINTCLEAR		(*((volatile unsigned long *)(VIC0_BASE + 0x1c)))
#define VIC1_SOFTINTCLEAR		(*((volatile unsigned long *)(VIC1_BASE + 0x1c)))
#define VIC2_SOFTINTCLEAR		(*((volatile unsigned long *)(VIC2_BASE + 0x1c)))
#define VIC3_SOFTINTCLEAR		(*((volatile unsigned long *)(VIC3_BASE + 0x1c)))

#define VIC0_PROTECTION		(*((volatile unsigned long *)(VIC0_BASE + 0x20)))
#define VIC1_PROTECTION		(*((volatile unsigned long *)(VIC1_BASE + 0x20)))
#define VIC2_PROTECTION		(*((volatile unsigned long *)(VIC2_BASE + 0x20)))
#define VIC3_PROTECTION		(*((volatile unsigned long *)(VIC3_BASE + 0x20)))

#define VIC0_SWPRIORITYMASK	(*((volatile unsigned long *)(VIC0_BASE + 0x24)))
#define VIC1_SWPRIORITYMASK	(*((volatile unsigned long *)(VIC1_BASE + 0x24)))
#define VIC2_SWPRIORITYMASK	(*((volatile unsigned long *)(VIC2_BASE + 0x24)))
#define VIC3_SWPRIORITYMASK	(*((volatile unsigned long *)(VIC3_BASE + 0x24)))

#define VIC0_VECADDR			(VIC0_BASE + 0x100)//(*((unsigned long *)(VIC0_BASE + 0x100)))
#define VIC1_VECADDR			(VIC1_BASE + 0x100)//(*((unsigned long *)(VIC1_BASE + 0x100)))
#define VIC2_VECADDR			(VIC2_BASE + 0x100)//(*((unsigned long *)(VIC2_BASE + 0x100)))
#define VIC3_VECADDR			(VIC3_BASE + 0x100)//(*((unsigned long *)(VIC3_BASE + 0x100)))

#define VIC0_VECPRIORITY		(*((volatile unsigned long *)(VIC0_BASE + 0x200)))
#define VIC1_VECPRIORITY		(*((volatile unsigned long *)(VIC1_BASE + 0x200)))
#define VIC2_VECPRIORITY		(*((volatile unsigned long *)(VIC2_BASE + 0x200)))
#define VIC3_VECPRIORITY		(*((volatile unsigned long *)(VIC3_BASE + 0x200)))

#define VIC0_ADDRESS			(*((volatile unsigned long *)(VIC0_BASE + 0xF00)))
#define VIC1_ADDRESS			(*((volatile unsigned long *)(VIC1_BASE + 0xF00)))
#define VIC2_ADDRESS			(*((volatile unsigned long *)(VIC2_BASE + 0xF00)))
#define VIC3_ADDRESS			(*((volatile unsigned long *)(VIC3_BASE + 0xF00)))

#define VIC0_PERID0			(*((volatile unsigned long *)(VIC0_BASE + 0xfe0)))
#define VIC1_PERID0			(*((volatile unsigned long *)(VIC1_BASE + 0xfe0)))
#define VIC2_PERID0			(*((volatile unsigned long *)(VIC2_BASE + 0xfe0)))
#define VIC3_PERID0			(*((volatile unsigned long *)(VIC3_BASE + 0xfe0)))

#define VIC0_PERID1			(*((volatile unsigned long *)(VIC0_BASE + 0xfe4)))
#define VIC1_PERID1			(*((volatile unsigned long *)(VIC1_BASE + 0xfe4)))
#define VIC2_PERID1			(*((volatile unsigned long *)(VIC2_BASE + 0xfe4)))
#define VIC3_PERID1			(*((volatile unsigned long *)(VIC3_BASE + 0xfe4)))

#define VIC0_PERID2			(*((volatile unsigned long *)(VIC0_BASE + 0xfe8)))
#define VIC1_PERID2			(*((volatile unsigned long *)(VIC1_BASE + 0xfe8)))
#define VIC2_PERID2			(*((volatile unsigned long *)(VIC2_BASE + 0xfe8)))
#define VIC3_PERID2			(*((volatile unsigned long *)(VIC3_BASE + 0xfe8)))

#define VIC0_PERID3			(*((volatile unsigned long *)(VIC0_BASE + 0xfec)))
#define VIC1_PERID3			(*((volatile unsigned long *)(VIC1_BASE + 0xfec)))
#define VIC2_PERID3			(*((volatile unsigned long *)(VIC2_BASE + 0xfec)))
#define VIC3_PERID3			(*((volatile unsigned long *)(VIC2_BASE + 0xfec)))

#define VIC0_PCELLID0			(*((volatile unsigned long *)(VIC0_BASE + 0xff0)))
#define VIC1_PCELLID0			(*((volatile unsigned long *)(VIC1_BASE + 0xff0)))
#define VIC2_PCELLID0			(*((volatile unsigned long *)(VIC2_BASE + 0xff0)))
#define VIC3_PCELLID0			(*((volatile unsigned long *)(VIC3_BASE + 0xff0)))

#define VIC0_PCELLID1			(*((volatile unsigned long *)(VIC0_BASE + 0xff4)))
#define VIC1_PCELLID1			(*((volatile unsigned long *)(VIC1_BASE + 0xff4)))
#define VIC2_PCELLID1			(*((volatile unsigned long *)(VIC2_BASE + 0xff4)))
#define VIC3_PCELLID1			(*((volatile unsigned long *)(VIC3_BASE + 0xff4)))

#define VIC0_PCELLID2			(*((volatile unsigned long *)(VIC0_BASE + 0xff8)))
#define VIC1_PCELLID2			(*((volatile unsigned long *)(VIC1_BASE + 0xff8)))
#define VIC2_PCELLID2			(*((volatile unsigned long *)(VIC2_BASE + 0xff8)))
#define VIC3_PCELLID2			(*((volatile unsigned long *)(VIC3_BASE + 0xff8)))

#define VIC0_PCELLID3			(*((volatile unsigned long *)(VIC0_BASE + 0xffc)))
#define VIC1_PCELLID3			(*((volatile unsigned long *)(VIC1_BASE + 0xffc)))
#define VIC2_PCELLID3			(*((volatile unsigned long *)(VIC2_BASE + 0xffc)))
#define VIC3_PCELLID3			(*((volatile unsigned long *)(VIC3_BASE + 0xffc)))

#define EXT_INT_0_CON			(*((volatile unsigned int *)0xE0200E00))
#define EXT_INT_1_CON			(*((volatile unsigned int *)0xE0200E04))
#define EXT_INT_2_CON			(*((volatile unsigned int *)0xE0200E08))
#define EXT_INT_3_CON			(*((volatile unsigned int *)0xE0200E0c))

#define	EXT_INT_0_MASK   		(*((volatile unsigned long *)0xE0200F00))
#define	EXT_INT_1_MASK   		(*((volatile unsigned long *)0xE0200F04))
#define	EXT_INT_2_MASK   		(*((volatile unsigned long *)0xE0200F08))
#define	EXT_INT_3_MASK   		(*((volatile unsigned long *)0xE0200F0C))

#define	EXT_INT_0_PEND   		(*((volatile unsigned long *)0xE0200F40))
#define	EXT_INT_1_PEND   		(*((volatile unsigned long *)0xE0200F44))
#define	EXT_INT_2_PEND   		(*((volatile unsigned long *)0xE0200F48))
#define	EXT_INT_3_PEND   		(*((volatile unsigned long *)0xE0200F4C))


#define INT_LIMIT				(96)

//INT NUM - VIC0
#define INT_IDX_EINT0				(0)
#define INT_IDX_EINT1				(1)
#define INT_IDX_EINT2				(2)
#define INT_IDX_EINT3				(3)
#define INT_IDX_EINT4				(4)
#define INT_IDX_EINT5				(5)
#define INT_IDX_EINT6				(6)
#define INT_IDX_EINT7				(7)
#define INT_IDX_EINT8				(8)
#define INT_IDX_EINT9				(9)
#define INT_IDX_EINT10			(10)
#define INT_IDX_EINT11			(11)
#define INT_IDX_EINT12			(12)
#define INT_IDX_EINT13			(13)
#define INT_IDX_EINT14			(14)
#define INT_IDX_EINT15			(15)
#define INT_IDX_EINT16_31			(16)
#define INT_IDX_Reserved17		(17) 
#define INT_IDX_MDMA				(18)
#define INT_IDX_PDMA0				(19)
#define INT_IDX_PDMA1				(20)
#define INT_IDX_TIMER0			(21)
#define INT_IDX_TIMER1			(22)
#define INT_IDX_TIMER2			(23)
#define INT_IDX_TIMER3			(24)
#define INT_IDX_TIMER4			(25)
#define INT_IDX_SYSTIMER			(26)
#define INT_IDX_WDT				(27)
#define INT_IDX_RTC_ALARM			(28)
#define INT_IDX_RTC_TICK			(29)
#define INT_IDX_GPIOINT			(30)
#define INT_IDX_FIMC3				(31)

//INT NUM - VIC1
#define INT_IDX_CORTEX0			(32+0)
#define INT_IDX_CORTEX1			(32+1)
#define INT_IDX_CORTEX2			(32+2)
#define INT_IDX_CORTEX3			(32+3)
#define INT_IDX_CORTEX4			(32+4)
#define INT_IDX_IEM_APC			(32+5)
#define INT_IDX_IEM_IEC			(32+6)
#define INT_IDX_Reserved39		(32+7)
#define INT_IDX_NFC				(32+8)
#define INT_IDX_CFC				(32+9)
#define INT_IDX_UART0				(32+10)
#define INT_IDX_UART1				(32+11)
#define INT_IDX_UART2				(32+12)
#define INT_IDX_UART3				(32+13)
#define INT_IDX_I2C				(32+14)
#define INT_IDX_SPI0				(32+15)
#define INT_IDX_SPI1				(32+16)
#define INT_IDX_SPI2				(32+17)
#define INT_IDX_AUDIO				(32+18)
#define INT_IDX_I2C_PMIC			(32+19)
#define INT_IDX_I2C_HDMI			(32+20)
#define INT_IDX_HSIRX				(32+21)
#define INT_IDX_HSITX				(32+22)
#define INT_IDX_UHOST				(32+23)
#define INT_IDX_OTG				(32+24)
#define INT_IDX_MSM				(32+25)
#define INT_IDX_HSMMC0			(32+26)
#define INT_IDX_HSMMC1			(32+27)
#define INT_IDX_HSMMC2			(32+28)
#define INT_IDX_MIPI_CSI			(32+29)
#define INT_IDX_MIPI_DSI			(32+30)
#define INT_IDX_ONENAND_AUDI		(32+31)

//INT NUM - VIC2
#define INT_IDX_LCD0				(64+0)
#define INT_IDX_LCD1				(64+1)
#define INT_IDX_LCD2				(64+2)
#define INT_IDX_LCD3				(64+3)
#define INT_IDX_ROTATOR			(64+4)
#define INT_IDX_FIMC_A			(64+5)
#define INT_IDX_FIMC_B			(64+6)
#define INT_IDX_FIMC_C			(64+7)
#define INT_IDX_JPEG				(64+8)
#define INT_IDX_2D					(64+9)
#define INT_IDX_3D					(64+10)
#define INT_IDX_MIXER				(64+11)
#define INT_IDX_HDMI				(64+12)
#define INT_IDX_HDMI_I2C			(64+13)
#define INT_IDX_MFC				(64+14)
#define INT_IDX_TVENC				(64+15)
#define INT_IDX_I2S0				(64+16)
#define INT_IDX_I2S1				(64+17)
#define INT_IDX_I2S2				(64+18)
#define INT_IDX_AC97				(64+19)
#define INT_IDX_PCM0				(64+20)
#define INT_IDX_PCM1				(64+21)
#define INT_IDX_SPDIF				(64+22)
#define INT_IDX_ADC 				(64+23)
#define INT_IDX_PENDN				(64+24)
#define INT_IDX_KEYPAD			(64+25)
#define INT_IDX_Reserved90		(64+26) 
#define INT_IDX_HASH				(64+27) 
#define INT_IDX_FEEDCTRL			(64+28) 
#define INT_IDX_PCM2				(64+29)
#define INT_IDX_SDM_IRQ			(64+30)
#define INT_IDX_SMD_FIQ			(64+31)

//INT NUM - VIC3
#define INT_IDX_IPC					(96+0)
#define INT_IDX_HOSTIF				(96+1)
#define INT_IDX_HSMMC3				(96+2)
#define INT_IDX_CEC					(96+3)
#define INT_IDX_TSI					(96+4)
#define INT_IDX_MDNIE0				(96+5)
#define INT_IDX_MDNIE1				(96+6)
#define INT_IDX_MDNIE2				(96+7)
#define INT_IDX_MDNIE3				(96+8)
#define INT_IDX_ADC1					(96+9)
#define INT_IDX_PENDN1				(96+10)
#define INT_IDX_ALL					(200)



#define INT_ALL_MASK		(0xffffffff)

void isr_routine(void);
void irq_init(void);
 void clear_vec_addr(void);
 void set_vec_addr(const unsigned int int_idx, void(*isr_func)(void));
 void int_enable(const unsigned int int_idx);
 void irq_handle(void);


#endif /*_IRQ_H_*/

